﻿using CMS.Util;
using Newtonsoft.Json;
using System;

namespace CMS.Infos
{
    public class DutyArrange : ICloneable, IAssignable
    {
        #region 私有内部字段
        [JsonIgnore]
        private uint _DutyClassWeekRaw;

        [JsonIgnore]
        private string _DutyClassWeek;

        [JsonIgnore]
        private uint _DutyClassTimeRaw;

        [JsonIgnore]
        private string _DutyClassTime;

        [JsonIgnore]
        private int? _DutyStart;

        [JsonIgnore]
        private int? _DutySpan;

        #endregion

        [JsonProperty(PropertyName = "term_id")]
        public int TermID { get; set; }

        [JsonProperty(PropertyName = "week")]
        public ushort Week { get; set; }

        [JsonProperty(PropertyName = "duty_classweek")]
        public uint DutyClassWeekRaw
        {
            get => _DutyClassWeekRaw; set
            {
                _DutyClassWeekRaw = value;
                _DutyClassWeek = null;
            }
        }

        [JsonProperty(PropertyName = "duty_classtime")]
        public uint DutyClassTimeRaw
        {
            get => _DutyClassTimeRaw; set
            {
                _DutyClassTimeRaw = value;
                _DutyClassTime = null;
                _DutyStart = null;
                _DutySpan = null;
            }
        }

        [JsonIgnore]
        public string DutyClassWeek
        {
            get
            {
                if (_DutyClassWeek == null)
                {
                    _DutyClassWeek = Utils.ConvertValue(DutyClassWeekRaw);
                }

                return _DutyClassWeek;
            }
            set => DutyClassWeekRaw = Utils.ConvertValue(value);
        }

        [JsonIgnore]
        public string DutyClassTime
        {
            get
            {
                if (_DutyClassTime == null)
                {
                    _DutyClassTime = Utils.ConvertValue(DutyClassTimeRaw);
                }

                return _DutyClassTime;
            }
            set => DutyClassTimeRaw = Utils.ConvertValue(value);
        }

        [JsonIgnore]
        public int DutyStart
        {
            get
            {
                if (_DutyStart == null)
                {
                    _DutyStart = Utils.CalcTimeStart(_DutyClassTimeRaw) + 1;
                }

                return _DutyStart.Value;
            }
        }

        [JsonIgnore]
        public int DutyTimeSpan
        {
            get
            {
                if (_DutySpan == null)
                {
                    _DutySpan = Utils.CalcTimeSpan(_DutyClassTimeRaw,14);
                }
                return _DutySpan.Value;
            }
        }

        [JsonProperty(PropertyName = "building")]
        public string Building { get; set; }

        [JsonProperty(PropertyName = "assistant_id")]
        public int AssistantID { get; set; }

        [JsonIgnore]
        public object Tag { get; set; }

        /// <summary>
        /// 助理的名字,此字段是临时字段,由客户端管理的
        /// </summary>
        [JsonIgnore]
        public string Name { get; set; }

        public object Assign(object src)
        {
            if (src is DutyArrange src2)
            {
                TermID = src2.TermID;
                DutyClassWeekRaw = src2.DutyClassWeekRaw;
                DutyClassTimeRaw = src2.DutyClassTimeRaw;
                Building = src2.Building;
                AssistantID = src2.AssistantID;
                Week = src2.Week;
            }
            else
            {
                throw new ArgumentException();
            }
            return this;
        }

        public object Clone()
        {
            return new DutyArrange().Assign(this);
        }

        public override int GetHashCode()
        {
            return (int)(TermID ^ Week ^ DutyClassWeekRaw ^ DutyClassTimeRaw ^ (Building?.GetHashCode() ?? 0) ^ AssistantID);
        }

        public override bool Equals(object obj)
        {
            if (obj is DutyArrange arrange)
            {
                return TermID == arrange.TermID && Week == arrange.Week &&
                    DutyClassWeekRaw == arrange.DutyClassWeekRaw &&
                    DutyClassTimeRaw == arrange.DutyClassTimeRaw &&
                    Building == arrange.Building &&
                    AssistantID == arrange.AssistantID;
            }
            else
            {
                return false;
            }
        }
    }
}
